<template>
	<el-container class="main-container full-height">
		<el-header class="main-header">
			<div class="float-left main-title">
				<img src="../../../assets/vform-logo.png" @click="openHome"/>
				<span class="bold">CY-FormDesigner</span> {{ $t('application.productTitle') }} <span class="version-span">Ver {{ vFormVersion }}</span>
			</div>
			<div style="font-size: 16px;font-weight: 600;text-align: center;">{{ designer.formTitle }}</div>
			<div class="float-right external-link">
				<el-dropdown v-if="showLink('languageMenu')" :hide-timeout="2000" @command="handleLanguageChanged">
					<span class="el-dropdown-link">{{ curLangName }}
						<el-icon style="vertical-align: -0.15em;height: 1.1em;width: 1.1em">
									<el-icon-arrow-down style="height: 1.1em;width: 1.1em"/>
								</el-icon></span>
					<template #dropdown>
						<el-dropdown-menu>
							<el-dropdown-item command="zh-cn">{{ $t('application.zh-cn') }}</el-dropdown-item>
							<el-dropdown-item command="en">{{ $t('application.en') }}</el-dropdown-item>
						</el-dropdown-menu>
					</template>
				</el-dropdown>
				<a v-if="showLink('externalLink')" @click="showManual" style="cursor: pointer;">
					<el-icon style="vertical-align: -0.15em;height: 1.1em;width: 1.1em">
						<sc-icon-vue-sfc style="height: 1.1em;width: 1.1em;color: #409EFF"/>
					</el-icon>
					{{ $t('application.document') }}</a>
			</div>
		</el-header>

		<el-container>
			<el-aside class="side-panel">
				<widget-panel :designer="designer"/>
			</el-aside>

			<el-container class="center-layout-container">
				<el-header class="toolbar-header">
					<toolbar-panel :designer="designer" ref="toolbarRef">
						<template v-for="(idx, slotName) in $slots" #[slotName]>
							<slot :name="slotName"></slot>
						</template>
					</toolbar-panel>
				</el-header>
				<el-main class="form-widget-main">
					<el-scrollbar class="container-scroll-bar" :style="{height: scrollerHeight}">
						<v-form-widget :designer="designer" :form-config="designer.formConfig"></v-form-widget>
					</el-scrollbar>
				</el-main>
			</el-container>

			<el-aside>
				<setting-panel :designer="designer" :selected-widget="designer.selectedWidget" :form-config="designer.formConfig" @edit-event-handler="testEEH"/>
			</el-aside>
		</el-container>

	</el-container>
</template>

<script>
import WidgetPanel from './widget-panel/index'
import ToolbarPanel from './toolbar-panel/index'
import SettingPanel from './setting-panel/index'
import VFormWidget from './form-widget/index'
import {createDesigner} from "@/components/designer/form-designer/designer"
import {
	addWindowResizeHandler, deepClone, getQueryParam, getAllContainerWidgets,
	getAllFieldWidgets, traverseAllWidgets
} from "@/utils/util"
import axios from 'axios'
import sysConfig from "@/config";
export default {
	name: "VFormDesigner",
	componentName: "VFormDesigner",
	mixins: [],
	components: {
		WidgetPanel,
		ToolbarPanel,
		SettingPanel,
		VFormWidget,
	},
	props: {
		formId: {type: String},
		/* 后端字段列表API */
		fieldListApi: {type: Object, default: null,},
		/* 禁止显示的组件名称数组 */
		bannedWidgets: {type: Array, default: () => []},
		designerConfig: {
			type: Object,
			default: () => {
				return {
					languageMenu: true,  //是否显示语言切换菜单
					externalLink: true,  //是否显示GitHub、文档等外部链接
					formTemplates: true,  //是否显示表单模板
					eventCollapse: true,  //是否显示组件事件属性折叠面板
					widgetNameReadonly: false,  //禁止修改组件名称
					clearDesignerButton: true,  //是否显示清空设计器按钮
					saveDesignerButton: true,  //是否显示保存表单按钮
					saveFormVersion: true,  //是否显示生成版
					previewFormButton: true,  //是否显示预览表单按钮
					importJsonButton: true,  //是否显示导入JSON按钮
					exportJsonButton: true,  //是否显示导出JSON器按钮
					exportCodeButton: true,  //是否显示导出代码按钮
					generateSFCButton: true,  //是否显示生成SFC按钮
					toolbarMaxWidth: 500,  //设计器工具按钮栏最大宽度（单位像素）
					toolbarMinWidth: 300,  //设计器工具按钮栏最小宽度（单位像素）
					presetCssCode: '',  //设计器预设CSS样式代码
					resetFormJson: true,  //是否在设计器初始化时将表单内容重置为空
				}
			}
		},
	},
	data() {
		return {
			vFormVersion: this.$CONFIG.VARIANT_FORM_VERSION,
			curLangName: '',
			curLocale: '',
			vsCodeFlag: false,
			caseName: '',
			scrollerHeight: 0,
			designer: createDesigner(this),
			fieldList: []
		}
	},
	provide() {
		return {
			serverFieldList: this.fieldList,
			getDesignerConfig: () => this.designerConfig,
			getBannedWidgets: () => this.bannedWidgets,
		}
	},
	created() {
		this.vsCodeFlag = getQueryParam('vscode') == 1
		this.caseName = getQueryParam('case')
	},
	mounted() {
		this.initLocale()

		this.scrollerHeight = window.innerHeight - 56 - 36 + 'px'
		addWindowResizeHandler(() => {
			this.$nextTick(() => {
				this.scrollerHeight = window.innerHeight - 56 - 36 + 'px'
			})
		})

		this.loadCase()
		this.loadFieldListFromServer();
		this.getFormJsonByFormId();
	},
	methods: {
		async getFormJsonByFormId() {
			let formId = deepClone(this.designer.formId)
			var res = await this.$API.bpm.bpmForm.getBpmFormJsonByFormId.get({formId: formId});
			if (res.code == 200) {
				this.designer.model=res.data.model;
				var formConfig = {};
				if (res.data.formConfig) {
					formConfig = JSON.parse(res.data.formConfig);
				}
				var widgetList = [];
				if (res.data.widgetList) {
					widgetList = JSON.parse(res.data.widgetList);
				}
				var resFormJson = {
					formConfig: formConfig,
					widgetList: widgetList
				}
				this.designer.setFormTitle(res.data.formTitle);
				this.setFormJson(resFormJson);
			} else {
				this.$alert(res.message, "提示", {type: 'error'})
			}
		},

		testEEH(eventName, eventParams) {
			console.log('test', eventName)
			console.log('test222222', eventParams)
		},
		showManual() {
			window.open(sysConfig.API_URL+'/template/workflowhandbook.pdf', "_blank");
		},
		showLink(configName) {
			if (this.designerConfig[configName] === undefined) {
				return true
			}
			return !!this.designerConfig[configName]
		},

		openHome() {
			if (this.vsCodeFlag) {
				const msgObj = {
					cmd: 'openUrl',
					data: {
						url: 'http://www.cyoasoft.com/'
					}
				}
				window.parent.postMessage(msgObj, '*')
			}
		},

		openUrl(event, url) {
			if (this.vsCodeFlag) {
				const msgObj = {
					cmd: 'openUrl',
					data: {
						url
					}
				}
				window.parent.postMessage(msgObj, '*')
			} else {
				let aDom = event.currentTarget
				aDom.href = url
				//window.open(url, '_blank') //直接打开新窗口，会被浏览器拦截
			}
		},

		loadCase() {
			if (!this.caseName) {
				return
			}

			axios.get(this.$CONFIG.MOCK_CASE_URL + this.caseName + '.txt').then(res => {
				if (res.data.code) {
					this.$message.error(this.$t('designer.hint.sampleLoadedFail'))
					return
				}

				this.setFormJson(res.data)
				this.$message.success(this.$t('designer.hint.sampleLoadedSuccess'))
			}).catch(error => {
				this.$message.error(this.$t('designer.hint.sampleLoadedFail') + ':' + error)
			})
		},

		initLocale() {
			this.curLocale = localStorage.getItem('v_form_locale')
			if (this.vsCodeFlag) {
				this.curLocale = this.curLocale || 'en'
			} else {
				this.curLocale = this.curLocale || 'zh-cn'
			}
			this.curLangName = this.$t('application.' + this.curLocale)
			this.changeLanguage(this.curLocale)
		},

		loadFieldListFromServer() {
			if (!this.fieldListApi) {
				return
			}

			let headers = this.fieldListApi.headers || {}
			axios.get(this.fieldListApi.URL, {'headers': headers}).then(res => {
				let labelKey = this.fieldListApi.labelKey || 'label'
				let nameKey = this.fieldListApi.nameKey || 'name'

				this.fieldList.splice(0, this.fieldList.length)  //清空已有
				res.data.forEach(fieldItem => {
					this.fieldList.push({
						label: fieldItem[labelKey],
						name: fieldItem[nameKey]
					})
				})
			}).catch(error => {
				this.$message.error(error)
			})
		},

		handleLanguageChanged(command) {
			this.changeLanguage(command)
			this.curLangName = this.$t('application.' + command)
		},

		changeLanguage(langName) {
			this.$i18n.locale = langName
			this.$TOOL.data.set("APP_LANG", langName);
		},

		setFormJson(formJson) {
			let modifiedFlag = false
			if (formJson) {
				if (typeof formJson === 'string') {
					modifiedFlag = this.designer.loadFormJson(JSON.parse(formJson))
				} else if (formJson.constructor === Object) {
					modifiedFlag = this.designer.loadFormJson(formJson)
				}

				if (modifiedFlag) {
					this.designer.emitHistoryChange()
				}
			}
		},

		getFormJson() {
			return {
				widgetList: deepClone(this.designer.widgetList),
				formConfig: deepClone(this.designer.formConfig)
			}
		},

		clearDesigner() {
			this.$refs.toolbarRef.clearFormWidget()
		},


		/**
		 * 刷新表单设计器
		 */
		refreshDesigner() {
			//this.designer.loadFormJson( this.getFormJson() )  //只有第一次调用生效？？

			let fJson = this.getFormJson()
			this.designer.clearDesigner(true)  //不触发历史记录变更
			this.designer.loadFormJson(fJson)
		},

		/**
		 * 预览表单
		 */
		previewForm() {
			this.$refs.toolbarRef.previewForm()
		},

		/**
		 * 导入表单JSON
		 */
		importJson() {
			this.$refs.toolbarRef.importJson()
		},

		/**
		 * 导出表单JSON
		 */
		exportJson() {
			this.$refs.toolbarRef.exportJson()
		},

		/**
		 * 导出Vue/HTML代码
		 */
		exportCode() {
			this.$refs.toolbarRef.exportCode()
		},

		/**
		 * 生成SFC代码
		 */
		generateSFC() {
			this.$refs.toolbarRef.generateSFC()
		},

		/**
		 * 获取所有字段组件
		 * @returns {*[]}
		 */
		getFieldWidgets(widgetList = null) {
			return widgetList ? getAllFieldWidgets(widgetList) : getAllFieldWidgets(this.designer.widgetList)
		},

		/**
		 * 获取所有容器组件
		 * @returns {*[]}
		 */
		getContainerWidgets(widgetList = null) {
			return widgetList ? getAllContainerWidgets(widgetList) : getAllContainerWidgets(this.designer.widgetList)
		},

		/**
		 * 升级表单json，以补充最新的组件属性
		 * @param formJson
		 */
		upgradeFormJson(formJson) {
			if (!formJson.widgetList || !formJson.formConfig) {
				this.$message.error('Invalid form json!')
				return
			}

			traverseAllWidgets(formJson.widgetList, (w) => {
				this.designer.upgradeWidgetConfig(w)
			})
			this.designer.upgradeFormConfig(formJson.formConfig)

			return formJson
		},

		getWidgetRef(widgetName, showError = false) {
			return this.$refs['formRef'].getWidgetRef(widgetName, showError)
		},

		getSelectedWidgetRef() {
			return this.$refs['formRef'].getSelectedWidgetRef()
		},

		//TODO: 增加更多方法！！

	}
}
</script>

<style lang="scss" scoped>
.el-container.main-container {
	background: #fff;

	:deep(aside) { /* 防止aside样式被外部样式覆盖！！ */
		margin: 0;
		padding: 0;
		background: inherit;
	}
}

.el-container.full-height {
	height: 100%;
	overflow-y: hidden;
}

.el-container.center-layout-container {
	min-width: 680px;
	border-left: 2px dotted #EBEEF5;
	border-right: 2px dotted #EBEEF5;
}

.el-header.main-header {
	border-bottom: 2px dotted #EBEEF5;
	height: 48px !important;
	line-height: 48px !important;
	min-width: 800px;
}

div.main-title {
	font-size: 18px;
	color: #242424;
	display: flex;
	align-items: center;
	justify-items: center;

	img {
		cursor: pointer;
		height: 36px;
	}

	span.bold {
		font-size: 20px;
		font-weight: bold;
		margin: 0 6px 0 6px;
	}

	span.version-span {
		font-size: 14px;
		color: #101F1C;
		margin-left: 6px;
	}
}

.float-left {
	float: left;
}

.float-right {
	float: right;
}

.el-dropdown-link {
	margin-right: 12px;
	cursor: pointer;
}

div.external-link {
	display: flex;
	align-items: center;

	a {
		font-size: 13px;
		text-decoration: none;
		margin-right: 10px;
		color: #606266;
	}
}

.el-header.toolbar-header {
	font-size: 14px;
	border-bottom: 1px dotted #CCCCCC;
	height: 42px !important;
	//line-height: 42px !important;
}

.el-aside.side-panel {
	width: 260px !important;
	overflow-y: hidden;
}

.el-main.form-widget-main {
	padding: 0;

	position: relative;
	overflow-x: hidden;
}

.container-scroll-bar {
	:deep(.el-scrollbar__wrap), :deep(.el-scrollbar__view) {
		overflow-x: hidden;
	}
}
</style>
